﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Asplode.Events;

namespace Asplode
{
    public class EventDispatcher
    {
        private Dictionary<Type, List<Object>> handlerRegistry
            = new Dictionary<Type, List<Object>>();

        public void Handle<T>(T t)
        {
            if (!handlerRegistry.ContainsKey(typeof(T)))
            {
                return;
            }
            foreach (Object obj in handlerRegistry[typeof(T)])
            {
                EventHandler<T> handler = obj as EventHandler<T>;
                handler.handle(t);
            }
        }

        public void addHandler<T>(EventHandler<T> handler)
        {

            if (!handlerRegistry.ContainsKey(typeof(T)))
            {
                handlerRegistry[typeof(T)] = new List<Object>();
            }
            handlerRegistry[typeof(T)].Add(handler);
        }


        //Please don't read this function.
        public void addAllHandlers(Object obj)
        {
            foreach (Type type in obj.GetType().GetInterfaces())
            {
                Type[] genArgs = type.GetGenericArguments();
                if (genArgs.Length == 1)
                {
                    Type genericEventHandler = typeof(EventHandler<>);
                    Type specificEventHandler = genericEventHandler.MakeGenericType(genArgs);

                    if (type.Equals(specificEventHandler))
                    {
                        if (!handlerRegistry.ContainsKey(genArgs[0]))
                        {
                            handlerRegistry[genArgs[0]] = new List<Object>();
                        }
                        handlerRegistry[genArgs[0]].Add(obj);
                    }
                }
            }
        }
    }

    public interface EventHandler<T>
    {
        void handle(T t);
    }
}
